﻿var yxcm = {};
yxcm.map = {};
yxcm.map.Current = null;

yxcm.map.EventListener = {
    line: {
        onsuccess: function() {
            var style = $.extend({}, yxcm.map.Style.line, yxcm.map.Current.lineBrush.style);
            var lineMarker = yxcm.map.Current.addMarker({ type: 'line', coordinates: yxcm.map.Current.mouseClickTrack, style: style });
            //            var pointMarker = yxcm.map.Current.addPointMarker({ coordinate: yxcm.map.Current.mouseClickTrack[0], style: yxcm.map.Style.point });
            //            pointMarker.relationalMarker = lineMarker;
            yxcm.map.Current.endDraw();
            yxcm.map.Current.notifyEvent('endDraw', lineMarker);
        }
    },

    area: {
        onsuccess: function() {
            var areaMarker = yxcm.map.Current.addAreaMarker({ coordinates: yxcm.map.Current.mouseClickTrack, style: yxcm.map.Style.area });
            var pointMarker = yxcm.map.Current.addPointMarker({ coordinate: areaMarker.getCenterCoordinate(), icon: yxcm.map.Style.area.icon });
            pointMarker.relationalMarker = areaMarker;
            yxcm.map.Current.endDraw();
            yxcm.map.Current.notifyEvent('endDraw', pointMarker);
        }
    },

    map: {
        onclicked: function() {
            if (yxcm.map.Current.isMouseClickTrack) {
                var maplet = yxcm.map.Current.maplet;
                var bounds = getBoundingClientRect(maplet.get().parentElement || maplet.get().parentNode);
                var left = maplet.mouseX - bounds.left;
                var top = maplet.mouseY - bounds.top;
                var latlng = maplet.getLatLng(left, top);
                yxcm.map.Current.mouseClickTrack.push(latlng);
            }

            if (yxcm.map.Current.brushType == 'point') {
                var pointMarker = yxcm.map.Current.addMarker({ type: 'point', coordinates: [yxcm.map.Current.mouseClickTrack[0]], style: yxcm.map.Style.poing });
                yxcm.map.Current.endDraw();
                yxcm.map.Current.notifyEvent('endDraw', pointMarker);
            }
        }
    }
}

yxcm.map.Style = {
    point: { lineColor: '#00ff00', lineThickness: 3, lineOpacity: 50, backgroundColor: '#ffffff', backgroundOpacity: 50, icon: '/Content/Css/Map/images/map_icon.gif' },
    line: { lineColor: '#436c83', lineThickness: 3, lineOpacity: 50, backgroundColor: '#ffffff', backgroundOpacity: 50, icon: '/Content/Css/Map/images/map_icon.gif' },
    area: { lineColor: '#00ff00', lineThickness: 3, lineOpacity: 50, backgroundColor: '#ffffff', backgroundOpacity: 50, icon: '/Content/Css/Map/images/map_icon.gif' }
}

yxcm.map.Util = {
    getCenterCoordinate: function(coordinates) {
        var lat = 0;
        var lng = 0;
        for (var i = 0; i < coordinates.length; i++) {
            lat += coordinates[i].lat;
            lng += coordinates[i].lng;
        }
        lat = Math.round((lat / coordinates.length) * 100000) / 100000;
        lng = Math.round((lng / coordinates.length) * 100000) / 100000;
        return new RLatLng(lat, lng);
    },

    getMouseCoordinate: function() {
        var maplet = yxcm.map.Current.maplet;
        var bounds = getBoundingClientRect(maplet.get().parentElement || maplet.get().parentNode);
        var left = maplet.mouseX - bounds.left;
        var top = maplet.mouseY - bounds.top;
        return maplet.getLatLng(left, top);
    }
}

yxcm.map.PointMarker = function(ownerMap, setting) {
    var me = this;
    this.eventHandlers = [];
    this.relationalMarker = null;
    this.detailIsShowing = false;
    this.type = "point";
    this.ownerMap = ownerMap;
    this.title = setting.title;
    this.style = $.extend({}, yxcm.map.Style.point, setting.style);

    this.id = setting.id;
    this.coordinate = setting.coordinates[0];

    this.marker = this.ownerMap.maplet.addBalloonMarker(this.coordinate, 1000, this.style.icon, this.title, null, null);
    this.detailContainer = $('<div class="detail-container"></div>');
    $(this.marker.div).append(this.detailContainer);

    $(this.marker.img).bind('mouseout.showTitle', function() {
        if (me.detailIsShowing) {
            $(me.marker.div).css('z-index', 599999);
        }
    });

    this.registerEvent = function(event, handler) {
        if (!this.eventHandlers[event]) {
            this.eventHandlers[event] = [];
        }
        this.eventHandlers[event].push(handler);
    }

    this.notifyEvent = function(event, arg) {
        if (me.eventHandlers[event]) {
            for (var i = 0; i < me.eventHandlers[event].length; i++) {
                me.eventHandlers[event][i](this, arg);
            }
        }
    }

    this.setTitle = function(value) {
        this.marker.setTitle(value);
        this.title = value;
    }

    this.setDetail = function(content) {
        this.detailContainer.html(content);
        if ($.browser.msie && $.browser.version == 6.0) {
            this.detailContainer.pngFix();
        }
        var offset = this.detailContainer.offset();
        var h = this.detailContainer.height();
        var w = this.detailContainer.width();
        this.detailContainer.css({ left: -(w / 2), top: -h - 30 });
        this.ownerMap.activeMarker = this;
        $(this.marker.div).css('z-index', 599999);
    }

    this.showDetail = function() {
        $(this.marker.div).css('z-index', 599999);
        this.notifyEvent('beforeShowDetail', this);
        this.ownerMap.moveTo(this.coordinate);
        this.detailContainer.show();
        this.detailIsShowing = true;
        this.notifyEvent('afterShowDetail', this);
    }

    this.hideDetail = function() {
        $(this.marker.div).css('z-index', 1001);
        this.detailIsShowing = false;
        this.detailContainer.hide();
        this.ownerMap.activeMarker = null;
    }

    this.destroyDetail = function() {
        this.hideDetail();
        this.detailContainer.empty();
    }

    this.destroy = function() {
        this.notifyEvent('beforeDestroy', this);
        this.destroyDetail();
        this.marker.destroy();
        if (this.relationalMarker) {
            this.relationalMarker.destroy();
        }
        this.ownerMap.maplet.refreshMarkers();
        this.ownerMap.maplet.refreshStaticMarkers();
        this.notifyEvent('afterDestroy', this);
    }

    this.show = function() {
        this.marker.show();
    }

    this.hide = function() {
        this.marker.hide();
    }

    $(this.marker.img).click(function() {
        me.notifyEvent('click', this);
    });

    if (setting.events) {
        for (var i in setting.events) {
            this.registerEvent(i, setting.events[i]);
        }
    }
}

yxcm.map.LineMarker = function(ownerMap, setting) {

    var me = this;
    this.marker = null;
    this.mouseEvent = null;
    this.eventHandlers = [];
    this.type = "line";
    this.id = setting.id;
    this.ownerMap = ownerMap;
    this.coordinates = setting.coordinates;
    this.style = $.extend({}, yxcm.map.Style.line, setting.style);
    this.detailContainer = $('<div class="detail-container"></div>');

    //    this.marker.initialized = function() {
    //        $(me.marker.stroke).mousedown(function(event) {
    //            if (event.button == 0) {
    //                me.mouseEvent = event;
    //                me.notifyEvent('click', this);
    //            }
    //        });
    //    }

    this.refresh = function() {
        if (this.marker) {
            this.marker.destroy();
        }
        var innerOpacity = this.style.lineOpacity;
        if ($.browser.mozilla) {
            innerOpacity = innerOpacity / 100;
        }
        this.marker = this.ownerMap.maplet.addStaticPathMarker(this.coordinates,
                        this.style.lineColor, this.style.lineThickness, innerOpacity);
        this.ownerMap.maplet.refreshMarkers();
        this.ownerMap.maplet.refreshStaticMarkers();
    }

    this.refresh();
    $(this.marker.div).append(this.detailContainer);

    this.registerEvent = function(event, handler) {
        if (!this.eventHandlers[event]) {
            this.eventHandlers[event] = [];
        }
        this.eventHandlers[event].push(handler);
    }

    this.notifyEvent = function(event, arg) {
        if (me.eventHandlers[event]) {
            for (var i = 0; i < me.eventHandlers[event].length; i++) {
                me.eventHandlers[event][i](this, arg);
            }
        }
    }

    this.setTitle = function(value) {
        this.title = value;
    }

    this.setDetail = function(content) {
        this.detailContainer.html(content);
        if ($.browser.msie && $.browser.version == 6.0) {
            this.detailContainer.pngFix();
        }
        var offset = this.detailContainer.offset();
        var h = this.detailContainer.height();
        var w = this.detailContainer.width();
        var mouseX = 0;
        var mouseY = 0;
        if ($.browser.msie) {
            mouseX = this.mouseEvent.X;
            mouseY = this.mouseEvent.Y;
        } else {
            mouseX = this.mouseEvent.layerX;
            mouseY = this.mouseEvent.layerY;
        }
        this.detailContainer.css({ left: mouseX - (w / 2), top: mouseY - (h) });
        this.ownerMap.activeMarker = this;
    }

    this.showDetail = function() {
        this.notifyEvent('beforeShowDetail', this);
        this.ownerMap.moveTo(yxcm.map.Util.getMouseCoordinate());
        var mouseX = 0;
        var mouseY = 0;
        if ($.browser.msie) {
            mouseX = this.mouseEvent.X;
            mouseY = this.mouseEvent.Y;
        } else {
            mouseX = this.mouseEvent.layerX;
            mouseY = this.mouseEvent.layerY;
        }
        this.detailContainer.css({ left: mouseX, top: mouseY });
        this.detailContainer.show();
        this.detailIsShowing = true;
        this.notifyEvent('afterShowDetail', this);
    }

    this.hideDetail = function() {
        $(this.marker.div).css('z-index', 1000);
        this.detailIsShowing = false;
        this.detailContainer.hide();
        this.ownerMap.activeMarker = null;
    }

    this.destroyDetail = function() {
        this.hideDetail();
        this.detailContainer.empty();
    }

    this.destroy = function() {
        this.marker.destroy();
        this.ownerMap.maplet.refreshMarkers();
        this.ownerMap.maplet.refreshStaticMarkers();
    }

    this.show = function() {
        $(this.marker.div).show();
    }

    this.hide = function() {
        $(this.marker.div).hide();
    }

    if (setting.events) {
        for (var i in setting.events) {
            this.registerEvent(i, setting.events[i]);
        }
    }
}

yxcm.map.AreaMarker = function(ownerMap, setting) {
    var me = this;
    this.eventHandlers = [];
    this.type = "area";
    this.id = setting.id;
    this.ownerMap = ownerMap;
    this.coordinates = setting.coordinates;
    this.style = $.extend({}, yxcm.map.Style.area, setting.style);
    this.marker = this.ownerMap.maplet.addStaticRegionMarker(this.coordinates,
            this.style.lineColor, this.style.backgroundColor, this.style.lineThickness);
    this.detailContainer = $('<div class="detail-container"></div>');
    $(this.marker.div).append(this.detailContainer);

    this.registerEvent = function(event, handler) {
        if (!this.eventHandlers[event]) {
            this.eventHandlers[event] = [];
        }
        this.eventHandlers[event].push(handler);
    }

    this.notifyEvent = function(event, arg) {
        if (me.eventHandlers[event]) {
            for (var i = 0; i < me.eventHandlers[event].length; i++) {
                me.eventHandlers[event][i](this, arg);
            }
        }
    }

    this.setDetail = function(content) {
        this.detailContainer.html(content);
        if ($.browser.msie && $.browser.version == 6.0) {
            this.detailContainer.pngFix();
        }
        this.ownerMap.activeMarker = this;
    }

    this.showDetail = function() {
        this.notifyEvent('beforeShowDetail', this);
        this.ownerMap.moveTo(this.coordinate);
        this.detailContainer.show();
        this.detailIsShowing = true;
        this.notifyEvent('afterShowDetail', this);
    }

    this.hideDetail = function() {
        $(this.marker.div).css('z-index', 1000);
        this.detailIsShowing = false;
        this.detailContainer.hide();
        this.ownerMap.activeMarker = null;
    }

    this.destroyDetail = function() {
        this.hideDetail();
        this.detailContainer.empty();
    }

    this.show = function() {
        $(this.marker.div).show();
    }

    this.hide = function() {
        $(this.marker.div).hide();
    }

    this.getCenterCoordinate = function() {
        return yxcm.map.Util.getCenterCoordinate(this.coordinates);
    }

    this.destroy = function() {
        this.marker.destroy();
        this.ownerMap.maplet.refreshMarkers();
        this.ownerMap.maplet.refreshStaticMarkers();
    }
}

yxcm.map.Map = function(setting) {
    yxcm.map.Current = this;
    this.markers = [];
    this.activeMarker = null;
    this.lineBrush = null;
    this.areaBrush = null;
    this.isDrawing = false;
    this.mouseClickTrack = [];
    this.isMouseClickTrack = false;
    this.brushType = '';
    this.eventHandlers = [];

    var tempObj = { isLock: true };
    this.maplet = new RMap(setting.left, setting.top, setting.width, setting.height, setting.lat, setting.lng, setting.zoom, IMG_SERVER + '/rt/mapdb');
    this.maplet.addListener(yxcm.map.EventListener.map, 'onclicked');

    $(setting.container).append(this.maplet.get());

    this.maplet.getCenterByPoints = function(latlngs) {
        var lat = 0;
        var lng = 0;
        for (var i = 0; i < latlngs.length; i++) {
            lat += latlngs[i].lat;
            lng += latlngs[i].lng;
        }
        lat = Math.round((lat / latlngs.length) * 100000) / 100000;
        lng = Math.round((lng / latlngs.length) * 100000) / 100000;
        return new RLatLng(lat, lng);
    }

    this.show = function() {
        this.maplet.show();
        toolbox = this.maplet.getToolBox(JS_SERVER + '/rapi/rwidget/rmap/toolbox/');
        toolbox.addCross();
        toolbox.addZoomBar();
        toolbox.addPan();
        //        toolbox.addTool(new RZoomoutTool(document.getElementById("PanZoomOut")));
        //        toolbox.addTool(new RZoominTool(document.getElementById("PanZoomIn")));
        //        toolbox.addTool(new REastTool(document.getElementById("PanEast")));
        //        toolbox.addTool(new RWestTool(document.getElementById("PanWest")));
        //        toolbox.addTool(new RSouthTool(document.getElementById("PanSouth")));
        //        toolbox.addTool(new RNorthTool(document.getElementById("PanNorth")));
        $(setting.container).pngFix();


        //        $(this.maplet.markerdiv).attr('id', 'MarkerDiv');
    }

    this.registerEvent = function(event, handler) {
        if (!this.eventHandlers[event]) {
            this.eventHandlers[event] = [];
        }
        this.eventHandlers[event].push(handler);
    }

    this.notifyEvent = function(event, arg) {
        if (this.eventHandlers[event]) {
            for (var i = 0; i < this.eventHandlers[event].length; i++) {
                this.eventHandlers[event][i](arg);
            }
        }
    }

    this.clearMouseClickTrack = function() {
        this.mouseClickTrack = [];
    }

    this.removeMarker = function(target) {
        if (typeof (target) == 'string' || typeof (target) == 'number') {
            target = this.findMarker(target);
        }

        if (target != null) {
            this.notifyEvent('beforeRemoveMarker', target);
            var arr = [];
            for (var i = 0; i < this.markers.length; i++) {
                if (this.markers[i] != target) {
                    arr.push(this.markers[i]);
                }
            }
            this.markers = arr;
            this.notifyEvent('afterRemoveMarker', target);
        }
    }

    this.findMarker = function(id) {
        for (var i = 0; i < this.markers.length; i++) {
            if (this.markers[i].id && this.markers[i].id == id && this.markers[i].type == 'point') {
                return this.markers[i];
            }
        }
        return null;
    }

    this.findShowingMarker = function() {
        for (var i = 0; i < this.markers.length; i++) {
            if (this.markers[i].detailIsShowing) {
                return this.markers[i];
            }
        }
        return null;
    }

    this.moveTo = function(coordinate) {
        this.maplet.smoothMoveWithoutEvents(coordinate.lat, coordinate.lng);
    }

    this.drawPoint = function() {
        if (this.areaBrush) {
            this.areaBrush.turnoff();
            this.areaBrush.clear();
        }
        if (this.lineBrush) {
            this.lineBrush.turnoff();
            this.lineBrush.clear();
        }

        this.beginDraw();
        this.isDrawing = true;
        this.brushType = "point";
        this.isMouseClickTrack = true;
    }

    this.drawLine = function(setting) {
        if (this.areaBrush) {
            this.areaBrush.turnoff();
            this.areaBrush.clear();
        }
        if (this.lineBrush) {
            this.lineBrush.turnoff();
            this.lineBrush.clear();
        }

        if (!this.lineBrush) {
            this.lineBrush = new RPathTool(document.getElementById(setting.elementId));
            this.lineBrush.setMaplet(this.maplet);
            this.lineBrush.Parent = tempObj;
            this.lineBrush.addListener(yxcm.map.EventListener.line, 'onsuccess');
        }

        if (setting && setting.style) {
            this.lineBrush.style = setting.style;
        }

        this.beginDraw();
        this.isDrawing = true;
        this.brushType = 'line';
        this.isMouseClickTrack = true;
        this.lineBrush.turnon(setting);
    }

    this.drawArea = function(setting) {
        if (this.lineBrush) {
            this.lineBrush.turnoff();
            this.lineBrush.clear();
        }

        if (this.areaBrush) {
            this.areaBrush.turnoff();
            this.areaBrush.clear();
        }

        if (!this.areaBrush) {
            this.areaBrush = new RPolygonTool(document.getElementById('marketArea'));
            this.areaBrush.setMaplet(this.maplet);
            this.areaBrush.Parent = tempObj;
            this.areaBrush.addListener(yxcm.map.EventListener.area, 'onsuccess');
            if (setting) {
                this.areaBrush.style = setting.style;
            }
        }

        this.beginDraw();
        this.isDrawing = true;
        this.brushType = 'area';
        this.isMouseClickTrack = true;
        this.areaBrush.turnon();
    }

    this.beginDraw = function() {
        $('#MarkerDiv').css('z-index', 99);
        this.notifyEvent('beginDraw', null);
        $(document).bind('keypress.cancelDraw', onCancelDraw);
    }

    this.endDraw = function() {
        this.cancelDraw();
        this.maplet.refreshStaticMarkers();
        this.maplet.refreshMarkers();
    }

    this.cancelDraw = function() {
        switch (this.brushType) {
            case 'line':
                this.lineBrush.turnoff();
                this.lineBrush.clear();
                break;
            case 'area':
                this.areaBrush.turnoff();
                this.areaBrush.clear();
                break;
        }
        this.isDrawing = false;
        this.isMouseClickTrack = false;
        this.clearMouseClickTrack();
        this.brushType = '';
        $(document).unbind('keypress.cancelDraw');
    }

    this.addMarker = function(setting) {
        var result = null;
        switch (setting.type) {
            case 'point':
                result = new yxcm.map.PointMarker(this, setting);
                break;
            case 'line':
                result = new yxcm.map.LineMarker(this, setting);
                break;
            case 'area':
                result = new yxcm.map.AreaMarker(this, setting);
                break;
        }

        result.registerEvent('beforeShowDetail', function(eventArg) {
            for (var i = 0; i < yxcm.map.Current.markers.length; i++) {
                $(yxcm.map.Current.markers[i].marker.div).css('z-index', 1000);
                if (yxcm.map.Current.markers[i].detailIsShowing) {
                    yxcm.map.Current.markers[i].destroyDetail();
                }
            }
            yxcm.map.Current.notifyEvent('beforeShowMarkerDetail', eventArg);
        });
        result.registerEvent('afterShowDetail', function(eventArg) {
            yxcm.map.Current.notifyEvent('afterShowMarkerDetail', eventArg);
        });
        result.registerEvent('afterDestroy', function(eventArg) {
            yxcm.map.Current.removeMarker(eventArg);
        });
        this.markers.push(result);
        if (setting.type != 'point') {
            setting.type = 'point';
            var m = this.addMarker(setting);
            m.referenceMarker = result;
            this.markers.push(m);
        }
        return result;
    }

    this.destroyAllMarkers = function() {
        for (var i = 0; i < this.markers.length; i++) {
            this.markers[i].destroy();
        }
        this.markers = [];
        this.maplet.clearMarkers();
        this.maplet.clearStaticMarkers();
    }

    this.hideAllMarkers = function() {
        for (var i = 0; i < this.markers.length; i++) {
            this.markers[i].hide();
        }
        this.maplet.clearMarkers();
        this.maplet.clearStaticMarkers();
    }

    this.showAllMarkers = function() {
        for (var i = 0; i < this.markers.length; i++) {
            this.markers[i].show();
        }
        this.maplet.clearMarkers();
        this.maplet.clearStaticMarkers();
    }

    this.refresh = function() {
        this.maplet.refreshStaticMarkers();
        this.maplet.refreshMarkers();
    }

    this.showMarkerDetail = function(marker) {
        this.activeMarker = marker;
        this.activeMarker.showDetail();
    }

    function onCancelDraw(event) {
        if (event.keyCode == '27') {
            yxcm.map.Current.cancelDraw();
        }
    }
}